package com.android.crypto;


import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.Key;
import java.security.PrivateKey;
import java.security.PublicKey;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;

public class CryController {
	private static final String TAG = "CryController";
	private static final String ORIGINAL_FILEPATH = "/Users/apple/Desktop/xiaoyu.txt";
	private static final String TEXT_FILEPATH = "/Users/apple/Desktop/cryptoText.data";
	private static final String KEY_FILEPATH = "/Users/apple/Desktop/cryptoKey.data";

	// 还需要通过RSA费对称加密算法来加密密钥。
	
	
	public static byte[] readFileByte(){
		byte[] bytes = null;
		File file = new File(ORIGINAL_FILEPATH);
		if(!file.exists()){
			System.out.println("文件不存在！！");
			return null;
		}
		try {
			FileInputStream fis = new FileInputStream(file);
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			copyStream(fis, baos);
			bytes = baos.toByteArray();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return bytes;
	}

	public static void saveFile(byte[] data, SecretKey skey, PublicKey puk) {
		// 获取Key的基本编码格式
		// System.out.println(skey.getFormat());
		// 获取Key的标准算法名称
		// System.out.println(skey.getAlgorithm());

		byte[] text = null;
		File file_text = new File(TEXT_FILEPATH);
		File file_key = new File(KEY_FILEPATH);


		try {
			if (!file_text.exists())
				file_key.createNewFile();
			if (!file_key.exists())
				file_key.createNewFile();

			text = encrypt(skey, data);
			System.out.println("1.加密明文");
			FileOutputStream fos_text = new FileOutputStream(file_text);
			FileOutputStream fos_key = new FileOutputStream(file_key);

			fos_text.write(text);
			fos_text.close();
			
			text = wrapKey(skey, puk);
			System.out.println("2.通过获取到的公钥加密对称密钥");
			fos_key.write(text);
			fos_key.close();

		} catch (Exception e) {
			System.out.println(TAG + ":保存密文失败！");
		}

	}
	//读取对应文件进行解密
	public static void readCryptoedFile(PrivateKey prk) {

		try {
			File file_text = new File(TEXT_FILEPATH);
			File file_key = new File(KEY_FILEPATH);
			FileInputStream fis_text = new FileInputStream(file_text);
			FileInputStream fis_key = new FileInputStream(file_key);

			// ByteArrayOutputStream bos = new ByteArrayOutputStream();
			// copyStream(fis_text,bos);

			int len = 0;
			// byte数组的长度一定要对应
			byte[] b = new byte[(int) (file_text.length())];
			len = fis_text.read(b);

			byte[] keyBytes = new byte[(int) file_key.length()];
			len = fis_key.read(keyBytes);

			SecretKey sKey = (SecretKey) unwrapKey(keyBytes, prk);
			System.out.println("3.通过非对称私钥解密对称密钥");

			byte[] min = decrypt(sKey, b);
			System.out.println("4.解密后的明文为：" + new String(min));

		} catch (Exception e) {
			System.out.println("读取文件失败！");
			e.printStackTrace();

		}
	}
	//把FileOutputStream读取到的字节存到ByteArrayOutputStream
	public static void copyStream(InputStream fis, ByteArrayOutputStream bos)
			throws Exception {
		byte[] buf = new byte[1024];
		int len = -1;
		while ((len = fis.read(buf)) != -1) {
			bos.write(buf, 0, len);
		}
	}

	//通过密钥对明文进行加密
	public static byte[] encrypt(SecretKey skey, byte[] data) {

		Cipher cipher;

		byte[] cryptoText = null;
		try {
			cipher = Cipher.getInstance("AES");
			cipher.init(Cipher.ENCRYPT_MODE, skey);
			cryptoText = cipher.doFinal(data);
		} catch (Exception e) {
			System.out.println(TAG + ":加密失败！");
		}

		return cryptoText;
	}

	// 通过AES密钥完成密文的解密
	public static byte[] decrypt(SecretKey sKey, byte[] data) {
		Cipher cipher;
		byte[] text = null;
		try {
			cipher = Cipher.getInstance("AES");
			cipher.init(Cipher.DECRYPT_MODE, sKey);
			text = cipher.doFinal(data);
		} catch (Exception e) {
			System.out.println(TAG + ":解密失败！");
		}

		return text;
	}

	// 打包密钥
	public static byte[] wrapKey(SecretKey sKey, PublicKey puk) {
		Cipher cipher;
		byte[] cryptoKey = null;
		try {
			System.out.println(puk.getAlgorithm());
			cipher = Cipher.getInstance("RSA/ECB/NoPadding");
			cipher.init(Cipher.WRAP_MODE, puk);
			cryptoKey = cipher.wrap(sKey);
		} catch (Exception e) {
			System.out.println(TAG + ":密钥打包失败");
		}
		return cryptoKey;

	}

	// 解包密钥
	public static Key unwrapKey(byte[] bytes, PrivateKey prk) {
		Cipher cipher;

		Key key = null;
		try {
			cipher = Cipher.getInstance("RSA");
			cipher.init(Cipher.UNWRAP_MODE, prk);
			key = cipher.unwrap(bytes, "AES", Cipher.SECRET_KEY);

		} catch (Exception e) {
			System.out.println(TAG + ":解包失败");
		}
		return key;

	}

}
